#pragma once
#ifndef _TEST_RESOURCE_LOCATOR_H_
#define _TEST_RESOURCE_LOCATOR_H_

#include <gtest/gtest.h>
#include "Log/LogSystem.h"
#include "vfs/resLoader/resourceLocator.h"
#include "vfs/resLoader/resourceType.h"

struct stLoc{
    stLoc(std::string l, std::string p, std::string u, std::string ps, std::string h, std::string po, std::string pa):
        loc(l), prot(p), user(u), pass(ps), host(h), port(po), path(pa)
    {}
    std::string loc;
    std::string prot;
    std::string user;
    std::string pass;
    std::string host;
    std::string port;
    std::string path;
};

class ResourceLocator_TestFixture: public ::testing::TestWithParam<stLoc>
{
    protected:
        ResourceType _genericResType;
        std::string _pLocation;
        std::string _specLocation;
        std::string _goodLocation1;
        std::string _goodLocationOnlyPassword;
        
        
public:
        
	virtual void SetUp(){
            _pLocation = "lala";
            _specLocation = "lolo";
            _goodLocation1 = "vfs://user:password@patatim:3030/patatam";
            _goodLocationOnlyPassword = "vfs://password@patatim/patatam";
            _genericResType = RTYPE_BIN;
            
            
	}
	virtual void TearDown(){

	}
};

////////////////////////////////////////////////////////////////////////////////
// PROTOCOL
////////////////////////////////////////////////////////////////////////////////
TEST_F(ResourceLocator_TestFixture, resource_locator_is_correctly_constructed)
{
    z3d::utils::ResourceLocator res("lala", "lolo", _genericResType);
    EXPECT_EQ(_pLocation, res.getPathLocation());
    EXPECT_EQ(_specLocation, res.getSpecificLocation());
    EXPECT_EQ(_genericResType, res.getResourceType());
}
TEST_F(ResourceLocator_TestFixture, ResourceLocator_init_protocol_is_correctly_set_when_correct)
{
    z3d::utils::ResourceLocator res(_goodLocation1, "lolo", _genericResType);
    res.init();
    EXPECT_EQ("vfs", res.getProtocol());
}

TEST_F(ResourceLocator_TestFixture, ResourceLocator_init_throws_exception_when_protocol_not_correctly_defined) {
    z3d::utils::ResourceLocator res("vfs:/patatim/patatam", "lolo", _genericResType);
    ASSERT_THROW(res.init(), z3d::core::resourceIncorrectFormatException);
}

////////////////////////////////////////////////////////////////////////////////
// USER AND PASSWORD
////////////////////////////////////////////////////////////////////////////////
TEST_F(ResourceLocator_TestFixture, ResourceLocator_init_user_is_correctly_set_when_correct)
{
    z3d::utils::ResourceLocator res(_goodLocation1, "lolo", _genericResType);
    res.init();
    ASSERT_EQ("user", res.getUserName());
}

TEST_F(ResourceLocator_TestFixture, ResourceLocator_init_password_is_correctly_set_when_correct)
{
    z3d::utils::ResourceLocator res(_goodLocation1, "lolo", _genericResType);
    res.init();
    ASSERT_EQ("password", res.getPassword());
}

TEST_F(ResourceLocator_TestFixture, ResourceLocator_init_when_no_hyphen_is_present_all_is_password)
{
    z3d::utils::ResourceLocator res(_goodLocationOnlyPassword, "lolo", _genericResType);
    res.init();
    ASSERT_EQ("password", res.getPassword());
    ASSERT_EQ("", res.getUserName());
}
TEST_F(ResourceLocator_TestFixture, ResourceLocator_init_empty_password_is_posible_whith_no_empty_user)
{
    std::string location = "vfs://onlyUser:@patatim/patatam";
    z3d::utils::ResourceLocator res(location, "lolo", _genericResType);
    res.init();
    ASSERT_EQ("", res.getPassword());
    ASSERT_EQ("onlyUser", res.getUserName());
}

TEST_F(ResourceLocator_TestFixture, ResourceLocator_init_empty_user_is_posible_whith_no_empty_password)
{
    std::string location = "vfs://:onlyPassword@patatim/patatam";
    z3d::utils::ResourceLocator res(location, "lolo", _genericResType);
    res.init();
    ASSERT_EQ("onlyPassword", res.getPassword());
    ASSERT_EQ("", res.getUserName());
}

////////////////////////////////////////////////////////////////////////////////
// HOST
////////////////////////////////////////////////////////////////////////////////
TEST_F(ResourceLocator_TestFixture, ResourceLocator_init_host_can_be_empty)
{
    std::string location = "vfs://:onlyPassword@/patatam";
    z3d::utils::ResourceLocator res(location, "lolo", _genericResType);
    res.init();
    ASSERT_EQ("", res.getHost());
    ASSERT_EQ("", res.getPort());
}

TEST_F(ResourceLocator_TestFixture, ResourceLocator_init_port_can_be_innexistent)
{
    std::string location = "vfs://:onlyPassword@patatim/patatam";
    z3d::utils::ResourceLocator res(location, "lolo", _genericResType);
    res.init();
    ASSERT_EQ("patatim", res.getHost());
    ASSERT_EQ("", res.getPort());
}

TEST_F(ResourceLocator_TestFixture, ResourceLocator_init_format_is_host_and_port)
{
    std::string location = "vfs://:onlyPassword@patatim:330/patatam";
    z3d::utils::ResourceLocator res(location, "lolo", _genericResType);
    res.init();
    ASSERT_EQ("patatim", res.getHost());
    ASSERT_EQ("330", res.getPort());
}

TEST_F(ResourceLocator_TestFixture, ResourceLocator_init_format_is_host_and_port_2)
{
    
    z3d::utils::ResourceLocator res(_goodLocation1, "lolo", _genericResType);
    res.init();
    ASSERT_EQ("patatim", res.getHost());
    ASSERT_EQ("3030", res.getPort());
}

TEST_F(ResourceLocator_TestFixture, ResourceLocator_init_the_path_is_correctly_extracted)
{
    
    z3d::utils::ResourceLocator res(_goodLocation1, "lolo", _genericResType);
    res.init();
    ASSERT_EQ("patatam", res.getPath());
}




TEST_P(ResourceLocator_TestFixture, ResourceLocator_init_parametrized_test)
{
    stLoc loc = GetParam();
    z3d::utils::ResourceLocator res(loc.loc, "lolo", _genericResType);
    res.init();
    ASSERT_EQ(loc.prot, res.getProtocol());
    ASSERT_EQ(loc.user, res.getUserName());
    ASSERT_EQ(loc.pass, res.getPassword());
    ASSERT_EQ(loc.host, res.getHost());
    ASSERT_EQ(loc.port, res.getPort());
    ASSERT_EQ(loc.path, res.getPath());
}

stLoc locations[] = {      
    stLoc("vfs://user:password@patatim:3030/patatam",          "vfs" , "user", "password", "patatim", "3030", "patatam"),
    stLoc("ftp://secure:megapassword@ftp.dodo.match.com/src",  "ftp" , "secure", "megapassword", "ftp.dodo.match.com", "", "src")
};
INSTANTIATE_TEST_CASE_P(PruebasCompletas,
                        ResourceLocator_TestFixture,
                        ::testing::ValuesIn(locations));
#endif //_TEST_RESOURCE_LOCATOR_H_